package com.bh.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bh.common.utils.DateUtils;
import com.bh.common.utils.SecurityUtils;
import com.bh.common.utils.StringUtils;
import com.bh.wms.domain.WmsWarehouse;
import com.bh.wms.domain.WmsWarehouseLocation;
import com.bh.wms.domain.WmsWarehouseZone;
import com.bh.wms.mapper.WmsWarehouseLocationMapper;
import com.bh.wms.mapper.WmsWarehouseMapper;
import com.bh.wms.mapper.WmsWarehouseZoneMapper;
import com.bh.wms.service.IWmsWarehouseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 仓库服务实现
 *
 * @author GPT
 */
@Service
public class WmsWarehouseServiceImpl extends ServiceImpl<WmsWarehouseMapper, WmsWarehouse> implements IWmsWarehouseService {

    @Autowired
    private WmsWarehouseZoneMapper warehouseZoneMapper;
    @Autowired
    private WmsWarehouseLocationMapper warehouseLocationMapper;

    @Override
    public WmsWarehouse selectWmsWarehouseById(Long id) {
        WmsWarehouse warehouse = baseMapper.selectById(id);
        if (warehouse != null) {
            List<WmsWarehouseZone> zones = warehouseZoneMapper.selectList(new LambdaQueryWrapper<WmsWarehouseZone>()
                    .eq(WmsWarehouseZone::getWarehouseId, id)
                    .orderByAsc(WmsWarehouseZone::getPickOrder, WmsWarehouseZone::getId));
            if (!CollectionUtils.isEmpty(zones)) {
                for (WmsWarehouseZone zone : zones) {
                    List<WmsWarehouseLocation> locations = warehouseLocationMapper.selectList(new LambdaQueryWrapper<WmsWarehouseLocation>()
                            .eq(WmsWarehouseLocation::getZoneId, zone.getId())
                            .orderByAsc(WmsWarehouseLocation::getPickOrder, WmsWarehouseLocation::getId));
                    zone.setLocations(locations);
                }
            }
            warehouse.setZones(zones);
        }
        return warehouse;
    }

    @Override
    public List<WmsWarehouse> selectWmsWarehouseList(WmsWarehouse query) {
        LambdaQueryWrapper<WmsWarehouse> wrapper = buildWarehouseQuery(query);
        return baseMapper.selectList(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertWmsWarehouse(WmsWarehouse entity) {
        fillCreateInfo(entity);
        return baseMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateWmsWarehouse(WmsWarehouse entity) {
        fillUpdateInfo(entity);
        return baseMapper.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteWmsWarehouseByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            return 0;
        }
        for (Long id : ids) {
            removeRelations(id);
        }
        return baseMapper.deleteBatchIds(Arrays.asList(ids));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteWmsWarehouseById(Long id) {
        removeRelations(id);
        return baseMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int changeStatus(WmsWarehouse entity) {
        fillUpdateInfo(entity);
        return baseMapper.updateById(entity);
    }

    private void fillCreateInfo(WmsWarehouse entity) {
        Date now = DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();
        if (entity.getStatus() == null) {
            entity.setStatus(1);
        }
        Long orgId = SecurityUtils.getOrgId();
        if (orgId != null) {
            entity.setOrganizationId(orgId);
        }
        entity.setCreateName(username);
        entity.setCreateTime(now);
        entity.setModifyName(username);
        entity.setModifyTime(now);
    }

    private void fillUpdateInfo(WmsWarehouse entity) {
        entity.setModifyName(SecurityUtils.getUsername());
        entity.setModifyTime(DateUtils.getNowDate());
    }

    private void removeRelations(Long warehouseId) {
        if (warehouseId == null) {
            return;
        }
        List<WmsWarehouseZone> zones = warehouseZoneMapper.selectList(new LambdaQueryWrapper<WmsWarehouseZone>()
                .eq(WmsWarehouseZone::getWarehouseId, warehouseId));
        if (!CollectionUtils.isEmpty(zones)) {
            for (WmsWarehouseZone zone : zones) {
                warehouseLocationMapper.delete(new LambdaQueryWrapper<WmsWarehouseLocation>()
                        .eq(WmsWarehouseLocation::getZoneId, zone.getId()));
            }
        }
        warehouseZoneMapper.delete(new LambdaQueryWrapper<WmsWarehouseZone>().eq(WmsWarehouseZone::getWarehouseId, warehouseId));
    }

    private LambdaQueryWrapper<WmsWarehouse> buildWarehouseQuery(WmsWarehouse query) {
        LambdaQueryWrapper<WmsWarehouse> wrapper = new LambdaQueryWrapper<>();
        if (query == null) {
            return wrapper.orderByDesc(WmsWarehouse::getCreateTime);
        }
        if (StringUtils.isNotEmpty(query.getName())) {
            wrapper.like(WmsWarehouse::getName, query.getName());
        }
        if (StringUtils.isNotEmpty(query.getCode())) {
            wrapper.like(WmsWarehouse::getCode, query.getCode());
        }
        if (query.getStatus() != null) {
            wrapper.eq(WmsWarehouse::getStatus, query.getStatus());
        }
        if (query.getOrganizationId() != null) {
            wrapper.eq(WmsWarehouse::getOrganizationId, query.getOrganizationId());
        }
        if (StringUtils.isNotEmpty(query.getWarehouseType())) {
            wrapper.eq(WmsWarehouse::getWarehouseType, query.getWarehouseType());
        }
        return wrapper.orderByDesc(WmsWarehouse::getCreateTime);
    }
}

